#lang racket


(provide λ.
         λid
         cλ
         call
         λcall
         finally)


(define (λ. f g)
  (λ args
    (f (apply g args))))

(define λid (λ (x) x))

(define cλ
  (λ args
    (λ cargs
      (apply (first args) (append (rest args) cargs)))))

(define (call fn . args)
  (apply fn args))

(define-syntax λcall
  (syntax-rules ()
    ((_ proc)
     (λ args (apply proc args)))))

(define-syntax finally
  (syntax-rules ()
    ((_ body proc)
     (with-handlers ((exn? (λ (e) (proc) (raise e))))
       (begin0 body (proc))))))